/*
 * urcbmb.cpp
 * urcbmb is a Arduino communication library for RC communication with URC bidirectional module bus
 * Licensed for use under the terms of the GNU Lesser General Public License v2.1
 * based on TWI/I2C library for Wiring & Arduino Copyright (c) 2006 Nicholas Zambetti
 * V0.1 	12.06.2013
 * 12.06.2013, Gerhard Herrmann (ghhermi@gmail.com), Munich, Germany
 * URC Project
 */

#include "urcbmb.h"
extern "C" {
	#include "twi.h"
}

void ( *urcbmb::user_onServo )( unsigned char, unsigned int );
void ( *urcbmb::user_onFunction )( unsigned char );

#define BMB_MASTERADRESS 0x77

/* 
 * Function urcbmb
 * Desc     constructor
 * Input    none
 * Output   none
 */
urcbmb::urcbmb() { }

/* 
 * Function begin
 * Desc     initalize twi
 * Input    manufactor: manufactor code, see project home page
 *          type: type code, see project home page
 *          measure: set if the device is able to create measure values
 *          master: set if the device is a master
 * Output   none
 */
void urcbmb::begin( unsigned char manufactor, unsigned char type, boolean measure, boolean master ) {
	
	// initialize variables
	bmb_manufactor = manufactor;
  bmb_type = type;
  bmb_measure = measure;
  bmb_master = master;

	// Master devices always have the unique adress 0x77
	// Slaves start with adress 0
	if( master ) 
	  twi_setAddress( BMB_MASTERADRESS );
	else
	  twi_setAddress( 0 );
	
	// Slave interrupt events
  twi_attachSlaveTxEvent( onRequestService );
  twi_attachSlaveRxEvent( onReceiveService );

	twi_init();
}

/* 
 * Function txServo
 * Desc     transmit a servo channel and value
 * Input    channel: channel number
 *          value: value of servo
 * Output   none
 */
void urcbmb::txServo( unsigned char channel, unsigned int value ) {
	//fill buffer with servo data
	txBuffer[ 0 ] = 0xff;			//identifier for servo
	txBuffer[ 1 ] = channel;  //channel number
	txBuffer[ 2 ] = value >> 8;   //value MSB
	txBuffer[ 3 ] = value & 0xff; //value LSB
	twi_writeTo( 0, txBuffer, 4, true, true );
}

/* 
 * Function txFunction
 * Desc     transmit a function bitfield
 * Input    value: bitfield of function
 * Output   none
 */
void urcbmb::txFunction( unsigned char value ) {
	//fill buffer with function data
	txBuffer[ 0 ] = value; //value
	twi_writeTo( 0, txBuffer, 1, true, true );
}

// behind the scenes function that is called when data is received
void urcbmb::onReceiveService( unsigned char* inBytes, int numBytes, boolean gcall ) {
	//check for general call is received
  if( gcall ) {
	  //check for servo value
	  if( inBytes[ 0 ] == 0xff ) {
		  //if not enough bytes received or no service routine defined
		  if(( numBytes < 4 ) || !user_onServo ) {
		    return;
	    }
	    user_onServo( inBytes[ 1 ], ( unsigned int )(( inBytes[ 2 ] << 8 ) + inBytes[ 3 ] ));
	  } else {
		  //if not enough bytes received or no service routine defined
		  if(( numBytes < 2 ) || !user_onFunction ) {
		    return;
	    }
	    user_onFunction( inBytes[ 1 ]);
	  }
  } else {
	  
  }
}

void urcbmb::onRequestService( void ) {

}

/* 
 * Function onServo
 * Desc     sets function called on servo value received
 * Input    function to call with: unsigned char channel: channel number
 *                                 unsigned int value: value of servo
 * Output   none
 */
void urcbmb::onServo( void (*function)( unsigned char, unsigned int )) {
	user_onServo = function;
}

/* 
 * Function onFunction
 * Desc     sets function called on function value received
 * Input    function to call with: unsigned char value: value of servo
 * Output   none
 */
void urcbmb::onFunction( void (*function)( unsigned char )) {
	user_onFunction = function;
}
